var fs = require('fs');
var minConfig = { removeComments: true, collapseWhitespace: true, minifyJS: true, minifyCSS: true };
//var minifier = require('html-minifier');
var $ = {},min = false;
(function(a){
  {{tools}}
})($)

var builded = {
  w_h:false,
  w_a:false,
  a_h:false
}

function minify(string,config){
  /*try{
    return minifier.minify(string, config)
  }catch(e){
    return string;
  }*/
  return string;
}

function build_w_h(fromPath,toPath,compile,buildConfig){
  if(!fs.existsSync(fromPath) || !fs.existsSync(toPath) || builded.w_h) return false;
  fromPath += '/';
  toPath += '/';
  builded.w_h = true;
  buildConfig = buildConfig || {};
  buildConfig.indexScript = buildConfig.indexScript || '<!--  -->'
  buildConfig.indexStyle = buildConfig.indexStyle || '<!--  -->'
  var config = fs.readFileSync(fromPath + 'app.json', 'utf-8');
  //移动框架代码
  $.node.copyFile(fromPath + 'common.wxss',toPath + 'css/common.css',function(s){
    return s.replace(/\spage|^page/gmi,'.page').replace(/rpx/igm,'px');
  });
  $.node.copyFile(fromPath + 'utils/common.js',toPath + 'js/common.js',function(s){
    return s.replace(/const \$(.+)require(.+);/,'').replace(/\$\./igm,'Y.').replace(/module.exports/,'Y.common');
  });
  $.node.copyFile(toPath + 'index.html',toPath + 'index.html',function(s){
    if(buildConfig && buildConfig.indexScript) s = s.replace(/\$\{indexScript\}/,buildConfig.indexScript);
    if(buildConfig && buildConfig.indexStyle) s = s.replace(/\$\{indexStyle\}/,buildConfig.indexStyle);
    return s.replace(/\?id=\d+__/gmi,'?id=' + new Date().getTime() + '__');
  });
  if(compile){
    $.node.copyFile(fromPath + 'config.js',toPath + 'js/config.js',function(s){
      //return s.replace(/wx\.\$/,'Y').replace(/APIURL:([^,]+),/g,"APIURL: '.',");
      return s.replace(/wx\.\$/,'Y');
    });
    $.node.copyFile(fromPath + 'app.js',toPath + 'js/app.js',function(s){
      s = s.replace(/require\(/g,'//require(');
      s = s.replace('G.App({','G.App(' + config + ',{');
      return s.replace(/wx\.\$/,'Y');
    });
    $.node.copyFile(fromPath + 'app.wxss',toPath + 'css/app.css',function(s){
      return s.replace(/^page/gmi,'.page').replace(/\spage/gmi,' .page').replace(/rpx/igm,'px').replace(/@import\s[^;]+;/g,'');
    });
  }
  //拷贝images文件夹
  $.node.copyFolder(fromPath + 'images',toPath + 'images');
  //拷贝asset文件夹
  $.node.copyFolder(fromPath + 'asset',toPath + 'asset');
  config = JSON.parse(config);
  if(!buildConfig.nodemvc && !compile) config.pages = config.pagesA;
  //编译业务代码
  for (i = 0; i < config.pages.length; i ++){
    (function(i){
      try{
        var _path = config.pages[i].split('/');
        _path.pop();
        _path = _path.join('/');
        $.node.copyFile(fromPath + _path,toPath + _path);
        var isComponent = (config.pages[i].indexOf('components/') == 0);
        var id = config.pages[i].replace(/\//g, '_');
        var js = fs.readFileSync(fromPath + config.pages[i] + '.js', 'utf-8');
        var json = fs.readFileSync(fromPath + config.pages[i] + '.json', 'utf-8');
        //去掉 /* */
        js = js.replace(/\/\*/gmi, '').replace(/\*\//gmi, '');
        js = js.replace('wx.$', 'Y');
        js = js.replace(/wx\./gmi, 'G.');
        js = js.replace(/G\.vue\(/, 'G.vue(' + json + ',');
        var wxss = fs.readFileSync(fromPath + config.pages[i] + '.wxss', 'utf-8');
        var tag = isComponent ? '.' : '#';
        // wxss = wxss.replace(/([\.#]?.+){/gim, tag + id + ' ' + '$1{').replace(/,([\.#]?.+){/gim, ',' + tag + id + ' ' + '$1{');
        // wxss = wxss.replace(new RegExp(tag + id + ' .Web','gmi'),'.Web ' + tag + id);
        // wxss = wxss.replace(new RegExp(tag + id + ' .iOS','gmi'),'.iOS ' + tag + id);
        // wxss = wxss.replace(new RegExp(tag + id + ' .Android','gmi'),'.Android ' + tag + id);
        // wxss = wxss.replace(/rpx/gmi,'px').replace(/^page|\spage/gmi,'');
        wxss = wxss.replace(/@import\s[^;]+;/g,'');
        var wxml = fs.readFileSync(fromPath + config.pages[i] + '.wxml', 'utf-8');
        wxml = $.Vnode.parseXml(wxml).toString(function(){
          switch(this.tagName){
            case 'view':
              this.tagName = 'div';
              break;
            case 'text':
              this.tagName = 'span';
              break;
            case 'switch':
              this.tagName = 'switch_'
              break;
            case 'image':
              this.tagName = 'img';
              break;
            case 'button':
              this.tagName = 'button_';
              break;
            default:
              break;
          }
          var attr = {};
          for(var key in this.attributes){
            if(key === 'wx:if'){
              attr['v-if'] = this.attributes['wx:if'].replace('{{','').replace('}}','');
            }else if(key === 'wx:elif'){
              attr['v-else-if'] = this.attributes['wx:elif'].replace('{{','').replace('}}','');
            }else if(key === 'wx:else'){
              attr['v-else'] = true;
            }else if(key === 'wx:for'){
              var items = this.attributes['wx:for'].replace('{{','').replace('}}',''),item = this.attributes['wx:for-item'] || 'item',index = this.attributes['wx:for-index'] || 'index';
              attr['v-for'] = '(' + item + ',' + index + ') in ' + items;
            }else if(key === 'wx:key'){
              attr['key'] = this.attributes['wx:key'];
            }else if(key === 'bindtap'){
              attr['@click'] = this.attributes['bindtap'];
            }else if(key === 'catchtap'){
              attr['@click.stop'] = this.attributes['catchtap'];
            }else if(key === 'bindinput'){
              attr['@change'] = this.attributes['bindinput'];
            }else if(key == 'bindlongpress'){
               attr['@touchstart'] = "on($event,'longpress','" + this.attributes['bindlongpress'] + "')"
            }else{
              var value = this.attributes[key];
              if(/^bind/.test(key)) {
                attr[key.replace('bind','@')] = this.attributes[key].replace('{{','').replace('}}','');
              }else if(/^catch/.test(key)) {
                attr[key.replace('catch','@') + '.stop'] = this.attributes[key].replace('{{','').replace('}}','');
              }else if(/^\{\{.+\}\}$/.test(this.attributes[key])){
                attr[':' + (key === 'id' ? 'ref' : key)] = this.attributes[key].replace(/^\{\{/,'').replace(/\}\}$/,'');
              }else if(key == 'style'){
                attr[':' + key] = "computStyle('" + this.attributes[key] + "')";
              }else if(key !== 'wx:for-item' && key !== 'wx:for-index'){
                attr[key === 'id' ? 'ref' : key] = this.attributes[key];
              }
            }
          }
          this.attributes = attr;
        })
        if (isComponent) {
          wxml = '<div class="' + id + '">\r\n' + wxml + '\r\n</div>';
        }else{
          wxml = '<template>\r\n' + wxml + '\r\n</template>';
        }
        if (isComponent){
          //wxml = minify(wxml, minConfig);
          js = js.replace('G.component({', 'window["' + id + '"](' + json + ',{\r\ntemplate:\'#TEMPLATE_' + id + '\',\r\n');
        }else{
          wxml += '\r\n<script type="text/javascript">\r\n' + js + '\r\n</script>\r\n<style scoped>\r\n' + wxss + '\r\n</style>';
          js = '';
          wxss = '';
        }
        if (min &&　compile) {
          wxml = minify(wxml, minConfig);
          wxss = minify(wxss, minConfig);
          js = minify(js, minConfig);
        }
        if(wxml) fs.writeFileSync(toPath + config.pages[i] + '.html', wxml);
        if(isComponent) fs.writeFileSync(toPath + config.pages[i] + '.css', '/* scoped */\r\n' + wxss);
        if(js) fs.writeFileSync(toPath + config.pages[i] + '.js', js);
        //if(compile) console.log('编译' + config.pages[i] + '成功');
      }catch(e){
        console.log('编译' + config.pages[i] + '出错!!!!');
        console.log(e);
      }
    })(i)
  }
}
function build_a_h(fromPath,toPath,compile,buildConfig){
  if(!fs.existsSync(fromPath) || !fs.existsSync(toPath) || builded.w_h || builded.a_h) return false;
  fromPath += '/';
  toPath += '/';
  builded.a_h = true;
  var config = JSON.parse(fs.readFileSync(fromPath + 'app.json', 'utf-8'));
  if(buildConfig && !buildConfig.nodemvc && !compile) config.pages = config.pagesA;
  buildConfig.indexScript = buildConfig.indexScript || '<!--  -->'
  buildConfig.indexStyle = buildConfig.indexStyle || '<!--  -->'
  if(compile){
    $.node.copyFile(fromPath + 'config.js',toPath + 'js/config.js',function(s){
      return s.replace(/my\.\$/,'Y').replace(/APIURL([^,]+),/g,"APIURL: '.',");
    });
    $.node.copyFile(fromPath + 'app.js',toPath + 'js/app.js',function(s){
      return s.replace(/my\.\$/,'Y');
    });
    $.node.copyFile(fromPath + 'app.acss',toPath + 'css/app.css',function(s){
      return s.replace(/^page/gmi,'.page').replace(/\spage/gmi,' .page').replace(/rpx/igm,'px').replace(/@import\s[^;]+;/g,'/*@import*/');
    });
  }
  //拷贝images文件夹
  $.node.copyFolder(fromPath + 'images',toPath + 'images');
  //拷贝asset文件夹
  $.node.copyFolder(fromPath + 'assets',toPath + 'assets');
  $.node.copyFile(toPath + 'index.html',toPath + 'index.html',function(s){
    if(buildConfig && buildConfig.indexScript) s = s.replace(/\$\{indexScript\}/,buildConfig.indexScript);
    if(buildConfig && buildConfig.indexStyle) s = s.replace(/\$\{indexStyle\}/,buildConfig.indexStyle);
    return s.replace(/\?id=\d+__/gmi,'?id=' + new Date().getTime() + '__');
  });
  //支付宝小程序app.json里面没有/components/ 需通过页面json提取出来
  var components = [],_components = {};
  for (var i = 0; i < config.pages.length; i ++){
    var json = fs.readFileSync(fromPath + config.pages[i] + '.json', 'utf-8');
    json = JSON.parse(json);
    if(json.usingComponents){
      for(var key in json.usingComponents){
        var name = json.usingComponents[key].replace(/\//g,'_');
        if(!_components[name]){
          components.push(json.usingComponents[key].replace('/',''));
          _components[name] = true;
        }
      }
    }
  }
  config.pages = config.pages.concat(components);
  //编译业务代码
  for (i = 0; i < config.pages.length; i ++){
    (function(i){
      var _path = config.pages[i].split('/');
      _path.pop();
      _path = _path.join('/');
      $.node.copyFile(fromPath + _path,toPath + _path);
      var isComponent = (config.pages[i].indexOf('components/') == 0);
      var id = config.pages[i].replace(/\//g, '_');
      var js = fs.readFileSync(fromPath + config.pages[i] + '.js', 'utf-8');
      var json = fs.readFileSync(fromPath + config.pages[i] + '.json', 'utf-8');
      //去掉 /* */
      js = js.replace(/\/\*/gmi, '').replace(/\*\//gmi, '');
      js = js.replace('my.$', 'Y');
      js = js.replace(/my\./gmi, 'G.');
      js = js.replace(/G\.vue\(\{/, 'G.vue("' + id + '",' + json + ',{');
      var wxss = fs.readFileSync(fromPath + config.pages[i] + '.acss', 'utf-8');
      var tag = isComponent ? '.' : '#';
      wxss = wxss.replace(/([\.#]?.+){/gim, tag + id + ' ' + '$1{').replace(/,([\.#]?.+){/gim, ',' + tag + id + ' ' + '$1{');
      wxss = wxss.replace(new RegExp(tag + id + ' .Web','gmi'),'.Web ' + tag + id);
      wxss = wxss.replace(new RegExp(tag + id + ' .iOS','gmi'),'.iOS ' + tag + id);
      wxss = wxss.replace(new RegExp(tag + id + ' .Android','gmi'),'.Android ' + tag + id);
      wxss = wxss.replace(/rpx/gmi,'px').replace(/^page|\spage/gmi,'');
      wxss = wxss.replace(/scoped/gmi,'').replace(/@import\s[^;]+;/g,'');
      var wxml = fs.readFileSync(fromPath + config.pages[i] + '.axml', 'utf-8');
      //id转ref
      var wxml = fs.readFileSync(fromPath + config.pages[i] + '.wxml', 'utf-8');
      wxml = $.Vnode.parseXml(wxml).toString(function(){
        switch(this.tagName){
          case 'view':
            this.tagName = 'div';
            break;
          case 'text':
            this.tagName = 'span';
            break;
          case 'image':
            this.tagName = 'img';
            break;
          case 'button':
            this.tagName = 'button_';
            break;
          default:
            break;
        }
        var attr = {};
        for(var key in this.attributes){
          if(key === 'a:if'){
            attr['v-if'] = this.attributes['a:if'].replace('{{','').replace('}}','');
          }else if(key === 'a:elif'){
            attr['v-else-if'] = this.attributes['a:elif'].replace('{{','').replace('}}','');
          }else if(key === 'a:else'){
            attr['v-else'] = true;
          }else if(key === 'a:for'){
            var items = this.attributes['a:for'].replace('{{','').replace('}}',''),item = this.attributes['a:for-item'] || 'item',index = this.attributes['a:for-index'] || 'index';
            attr['v-for'] = '(' + item + ',' + index + ') in ' + items;
          }else if(key === 'a:key'){
            attr['key'] = this.attributes['a:key'];
          }else if(key === 'onTap'){
            attr['@click'] = this.attributes['onTap'];
          }else if(key === 'onInput'){
            attr['@change'] = this.attributes['onInput'];
          }else if(key == 'onLongTap'){
            attr['@touchstart'] = "on($event,'longpress','" + this.attributes['onLongTap'] + "')"
          }else{
            var value = this.attributes[key];
            if(/^on([A-Z])([a-z,A-Z]+)/.test(key)) {
              attr[key.replace(/^on([A-Z])(\w+)/,function($0,$1,$2){
                return '@' + $1.toLowerCase() + $2;
              })] = this.attributes[key].replace('{{','').replace('}}','');
            }else if(/^\{\{.+\}\}$/.test(this.attributes[key])){
              attr[':' + (key === 'id' ? 'ref' : key)] = this.attributes[key].replace(/^\{\{/,'').replace(/\}\}$/,'');
            }else if(key == 'style'){
              attr[':' + key] = "computStyle('" + this.attributes[key] + "')";
            }else if(key !== 'a:for-item' && key !== 'a:for-index'){
              attr[key === 'id' ? 'ref' : key] = this.attributes[key];
            }
          }
        }
        this.attributes = attr;
      })
      if (isComponent) {
        wxml = '<div class="' + id + '">' + wxml + '</div>';
      }else{
        wxml = '<template>' + wxml + '</template>';
      }
      if (isComponent){
        //wxml = minify(wxml, minConfig);
        js = js.replace('G.component(Component,{', 'window["' + id + '"](' + json + ',{\r\ntemplate:\'#TEMPLATE_' + id + '\',\r\n');
      }else{
        wxml += '\r\n<script type="text/javascript">\r\n' + js + '\r\n</script>';
        js = '';
      }
      if (min == '-min' && compile) {
        wxml = minify(wxml, minConfig);
        wxss = minify(wxss, minConfig);
        js = minify(js, minConfig);
      }
      if(wxml) fs.writeFileSync(toPath + config.pages[i] + '.html', wxml);
      fs.writeFileSync(toPath + config.pages[i] + '.css', wxss);
      if(js) fs.writeFileSync(toPath + config.pages[i] + '.js', js);
    })(i)
  }
}
function build_w_a(fromPath,toPath,compile,replace){
  if(!fs.existsSync(fromPath) || !fs.existsSync(toPath) || builded.w_a) return false;
  fromPath += '/';
  toPath += '/';
  builded.w_a = true;
  var config = JSON.parse(fs.readFileSync(fromPath + 'app.json', 'utf-8'));
  //移动框架代码
  var codeFiles = [
    'common.wxss',
    'utils/common.js',
    'app.js'
  ];
  for(i = 0; i < codeFiles.length; i ++){
    var from = fromPath + codeFiles[i];
    var to = toPath + codeFiles[i].replace(/wxss/,'acss').replace(/wxml/,'axml');
    $.node.copyFile(from,to,replace || {},function(s){
      return s.replace(/\.wxss/igm,'.acss').replace(/wx\./gmi, 'my.');
    });
  }
  //拷贝images文件夹
  $.node.copyFolder(fromPath + 'images',toPath + 'images');
  //拷贝asset文件夹
  $.node.copyFolder(fromPath + 'assets',toPath + 'assets');
  //编译业务代码
  for (i = 0; i < config.pages.length; i ++){
    (function(i){
      var isComponent = (config.pages[i].indexOf('components/') == 0);
      $.node.copyFile(fromPath + config.pages[i] + '.js',toPath + config.pages[i] + '.js',function(js){
        js = js.replace(/wx\./gmi, 'my.');
        if(isComponent) js = js.replace('G.component({','G.component(Component,{')
        return js;
      })
      $.node.copyFile(fromPath + config.pages[i] + '.json',toPath + config.pages[i] + '.json');
      $.node.copyFile(fromPath + config.pages[i] + '.wxss',toPath + config.pages[i] + '.acss',function(wxss){
        return wxss.replace(/\.wxss/gmi,'.acss');
      })
      $.node.copyFile(fromPath + config.pages[i] + '.wxml',toPath + config.pages[i] + '.axml',function(wxml){
        //wx:转换
        wxml = wxml.replace(/\swx:/gmi, ' a:');
        //bind事件转on
        wxml = wxml.replace(/\sbind([a-z])([a-z,A-Z]+)=/gmi, function($0,$1,$2){
          return ' on' + $1.toUpperCase() + $2 + '=';
        });
        //组件传递事件
        wxml = wxml.replace(/\sbind:(\w+)=/gmi, function($0,$1){
          var first = $1.charAt(0).toUpperCase();
          $1 = first + $1.substring(1,$1.length);
          return ' on' + $1;
        });
        return wxml;
      })
    })(i)
  }
}
function build(from,to,_min,compile,config){
  min = _min;
  build_w_h(from + 'WeChat',to + 'H5',compile,config);
  build_w_a(from + 'WeChat',to + 'Alipay',compile,config);
  build_a_h(from + 'Alipay',to + 'H5',compile,config);
}
if(process.argv[2] == 'compile'){
  build('./','./',process.argv[3] == '-min',true);
}else{
  module.exports = build;
}